package pro.model.data;


import java.io.*;
import java.rmi.*;
import java.util.*;
import pro.model.data.server.*;
import pro.view.adaptor.*;

/**
 * @author  sangwo.y
 */
public class HighScore extends Observable implements Serializable  {
	
	/**
	 * @author  sangwo.y
	 */
	public class Item implements Serializable, Comparable {
		
		private static final long serialVersionUID = 1L;
		String player;
		int duration;
		int score;
		
		public Item(String player, int duration, int score) {
			this.player=player;
			this.duration=duration;
			this.score=score;
			
		}
		
		/**
		 * @return  the player
		 * @uml.property  name="player"
		 */
		public String getPlayer() {
			return player;
		}
		
		/**
		 * @return  the duration
		 * @uml.property  name="duration"
		 */
		public int getDuration() {
			return duration;
		}
		
		/**
		 * @return  the score
		 * @uml.property  name="score"
		 */
		public int getScore() {
			return score;
		}
		
		public String getStringDuration() {
			return Wrapper.getStringDuration(duration);

		}
		
		public String toString() {
			return player+" "+duration+" "+score;
		}

		public int compareTo(Object o) {
			// -1 - this < o; 0 this == o; 1 this > o
			if (this==o) return 0;
			
			if (this.score==((Item)o).score) {
				if (this.duration==((Item)o).duration) {
					return this.player.compareTo(((Item) o).player);
				} else return this.duration - ((Item) o).duration;
			} else return this.score - ((Item)o).score;
			
		}
		
		public boolean equals(Object o) {
			if (this.compareTo(o)==0) return true;
			return false;
		}
	}
	
	private final String SERVER_ADRESS = "cisws121-010.idcn.mil.intra";
	private List<Item> scores;
	private List<Item> bestScores;
	
	private IHighScoreServer server;
	private boolean connected = false;
	
	private String client;
	
	public HighScore() {
		scores = new ArrayList<Item>();
		bestScores = new ArrayList<Item>();
		
	    if (System.getSecurityManager() == null){
	        System.setSecurityManager(new RMISecurityManager());
	    }
     
	    try {
			 server = (IHighScoreServer) Naming.lookup
		        ("//"+SERVER_ADRESS+"/IHighScoreServer");
			 System.out.println("Client <--- connected");
			 connected = true;
	    } catch (Exception e) {System.out.println(e);}

		//load(); can't to this because not an observer yet in gv		
	}
	
	/**
	 * @return  the connected
	 * @uml.property  name="connected"
	 */
	public boolean isConnected() {
		return connected;
	}
	
	@SuppressWarnings("unchecked")
	public boolean loadFromServer() {
//		System.out.println("loading from svr");
		Object [][] tmp;
		try {
			tmp = server.load();
			scores.clear();
			bestScores.clear();
			for (int i=0; i<tmp.length; i++) {
				String player = (String)tmp[i][0];
//				System.out.println(player);
				Integer duration = (Integer)tmp[i][1];
//				System.out.println(tmp[i][1]);
				Integer score = (Integer)tmp[i][2];
//				System.out.println(score);
				Item item = new Item(player, duration, score);
				scores.add(item);
//				System.out.println(client);
				if (item.getPlayer().equals(client)) 
					bestScores.add(item);
			}
			
		} catch (Exception e) {System.out.println(e); return false;}		
		signal(this);
		return true;
	}
	
	public void setClient(String client) {
		this.client=client;
	}
	
	@SuppressWarnings("unchecked")
	public void addGame(String player, int duration, int score) {
		boolean isOk = false;
		Item item = new Item(player, duration, score);
		bestScores.add(item);
		cleanBestScores();
		if (bestScores.contains(item)) isOk=true;
		
		if (isOk) {				
			scores.add(item);
			if (connected) {
				try {
					server.store(player, duration, score);
				} catch (Exception e) {System.out.println(e);}
			}
		}
		signal(this);
	}
	
	@SuppressWarnings("unchecked")
	public void cleanBestScores() {		
		List<Item> tmpList = new ArrayList<Item>();
		Collections.sort(bestScores);
		int count = 0; 
		for (Item i: bestScores) {			
			if (count<3) tmpList.add(i);
			count++;
		}
		bestScores=tmpList;		
	}
	
	
	@SuppressWarnings("unchecked")
	public Object[][] getTableModel() {
		List<Item> tmpList = scores;
		System.out.println(bestScores);
		Collections.sort(tmpList);
		Object[][] model = new Object[tmpList.size()][3];
		int count=0;
		for (Item item: tmpList) {
			model[count][0]=item.getPlayer();
			model[count][1]=item.getStringDuration();
			model[count][2]=item.getScore();
			count++;
		}
		return model;
	}
	
	public String toString() {
		return scores.toString(); 
	}
	
	public int hashCode() {
		return scores.hashCode();
	}
	
	private void signal(Object o) {
		setChanged();
		notifyObservers(o);
	}
	

}

